Skip to content

Add UDS peer credentials on Posix.Context - #192

Open
VictorDebray wants to merge 3 commits into
grpc:mainfrom
VictorDebray:feat/add-uds-peer-credentials-on-posix-context
Open

Add UDS peer credentials on Posix.Context#192
VictorDebray wants to merge 3 commits into
grpc:mainfrom
VictorDebray:feat/add-uds-peer-credentials-on-posix-context

Conversation

@VictorDebray

Copy link
Copy Markdown

Gives us kernel-validated peer credentials for Unix domain socket connections as a field on HTTP2ServerTransport.Posix.Context.

Adds HTTP2ServerTransport.Posix.UDSCredentials { pid, uid, gid } and a matching udsCredentials field on Posix.Context. The field is populated in the existing channel-init closure that already populates peerCertificate / peerCertificateChain, by calling a new internal helper.
The helper reads SO_PEERCRED (Linux) or LOCAL_PEEREPID + LOCAL_PEERCRED (Darwin).

Returns nil for non-UDS channels, on platforms without peer-credential support, and on any read failure, so nothing changes for existing transports.

Gives us kernel-validated peer credentials for Unix domain socket
connections as a field on `HTTP2ServerTransport.Posix.Context`.

Adds `HTTP2ServerTransport.Posix.UDSCredentials { pid, uid, gid }` and a
matching `udsCredentials` field on `Posix.Context`. The field is populated
in the existing channel-init closure that already populates
`peerCertificate` / `peerCertificateChain`, by calling a new internal
helper in `Sources/GRPCNIOTransportHTTP2Posix/UDSPeerCredentials.swift`
which uses `SocketOptionProvider.unsafeGetSocketOption` to read
`SO_PEERCRED` (Linux) or `LOCAL_PEEREPID` + `LOCAL_PEERCRED` (Darwin).

Returns `nil` for non-UDS channels, on platforms without peer-credential
support, and on any read failure, so nothing changes for existing
transports.

`struct ucred` (Linux) and `struct xucred` (Darwin) are mirrored locally:
glibc 2.36+ guards `ucred` behind `_GNU_SOURCE`, which the Swift Glibc
module does not reliably set, and the Swift Darwin overlay is not
guaranteed to re-export `xucred` across SDK versions.
@linux-foundation-easycla

linux-foundation-easycla Bot commented Aug 3, 2026

Copy link
Copy Markdown

CLA Signed
The committers listed above are authorized under a signed CLA.

  • ✅ login: VictorDebray / name: Victor Debray (20bfc87)

@VictorDebray

Copy link
Copy Markdown
Author

/easycla

1 similar comment
@VictorDebray

Copy link
Copy Markdown
Author

/easycla

@glbrntt glbrntt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll also need tests for these changes

Comment thread Sources/GRPCNIOTransportHTTP2Posix/HTTP2ServerTransport+Posix.swift Outdated
Comment thread Sources/GRPCNIOTransportHTTP2Posix/UDSPeerCredentials.swift Outdated
Comment thread Sources/GRPCNIOTransportHTTP2Posix/UDSPeerCredentials.swift Outdated
Comment thread Sources/GRPCNIOTransportHTTP2Posix/UDSPeerCredentials.swift Outdated
Comment thread Sources/GRPCNIOTransportHTTP2Posix/UDSPeerCredentials.swift Outdated
Comment thread Sources/GRPCNIOTransportHTTP2Posix/UDSPeerCredentials.swift Outdated
Comment thread Sources/GRPCNIOTransportHTTP2Posix/HTTP2ServerTransport+Posix.swift Outdated
- Remove the leftover internal TODO comment.
- Rename `populateUDSCredentials` to `makeUDSCredentials`: it creates and
  returns a value rather than populating one in place.
- Skip the socket option reads entirely unless the channel is backed by a Unix
  domain socket.
- Spell out the returned type instead of relying on `.init`.
- Don't expose `pid_t`/`uid_t`/`gid_t` in public API. Add nominal `ProcessID`,
  `UserID` and `GroupID` wrappers holding fixed-size integers, following the
  shape of `SocketAddress.VirtualSocket.ContextID`.
- Annotate the new API with `@available(gRPCSwiftNIOTransport 2.10, *)` and
  bump `nextMinorVersion` so the 2.10 availability macro is defined.
- Make `UDSCredentials` `Hashable` with `var` properties, matching the
  feedback given for `VsockCredentials`.

Still outstanding: the Linux `struct ucred` mirror should be replaced by a C
shim defining `_GNU_SOURCE`, and tests are still needed.
Replaces the hand-written mirror of Linux's `struct ucred` with a C shim target that defines `_GNU_SOURCE`, following the shape of SwiftNIO's `CNIOLinux`.

glibc only declares `struct ucred` when `_GNU_SOURCE` is defined and the Swift Glibc module doesn't reliably set it, which is why the type was previously redeclared in Swift.
`CGRPCNIOTransportLinux` defines `_GNU_SOURCE` via `cSettings` and includes <sys/socket.h>, so `ucred` and `SO_PEERCRED` are imported from the platform headers instead of being duplicated.
The header is `#ifdef __linux__`-guarded and `#error`s if `_GNU_SOURCE` is somehow absent, and the target is only a dependency on Linux.

The Darwin mirror of `struct xucred` is also removed: `xucred` is imported by the Swift Darwin overlay, so it can be used directly. `cr_groups` imports as a fixed-size tuple, which replaces the pointer rebinding that read the primary group out of the local copy.
/// recorded by the kernel when the connection was established; they are not
/// re-read per request.
@available(gRPCSwiftNIOTransport 2.10, *)
public struct UDSCredentials: Hashable, Sendable {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None of these types are specific to server transport so shouldn't be nested within HTTP2ServerTransport. I think they can be moved to their own file in the core module.

Comment on lines +331 to +337
public var pid: ProcessID

/// The user ID of the peer process.
public var uid: UserID

/// The group ID of the peer process.
public var gid: GroupID

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we spell these out rather than abbreviating them?

Comment thread Package.swift
Comment on lines +103 to +111
// C-module exposing Linux declarations which glibc guards behind `_GNU_SOURCE`, such as
// `struct ucred` and `SO_PEERCRED`.
.target(
name: "CGRPCNIOTransportLinux",
dependencies: [],
cSettings: [
.define("_GNU_SOURCE")
]
),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies, it turns out that we don't need to go as far as this: we can just add the C settings to the posix module, no need for a C module at all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants